package com.xjgz.aio.socket.pro.extension.plugins;

import java.io.IOException;
import java.net.SocketOption;
import java.net.StandardSocketOptions;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.HashMap;
import java.util.Map;

public class SocketOptionPlugin<T> extends AbstractPlugin<T> {

    private final Map<SocketOption<Object>, Object> optionMap = new HashMap<>();

    @Override
    public AsynchronousSocketChannel shouldAccept(AsynchronousSocketChannel channel) {
        setOption(channel);
        return super.shouldAccept(channel);
    }

    public void setOption(AsynchronousSocketChannel channel) {
        try {
            if (!optionMap.containsKey(StandardSocketOptions.TCP_NODELAY)) {
                channel.setOption(StandardSocketOptions.TCP_NODELAY, true);
            }
            for (Map.Entry<SocketOption<Object>, Object> entry : optionMap.entrySet()) {
                channel.setOption(entry.getKey(), entry.getValue());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public final SocketOptionPlugin<T> setOption(SocketOption<Object> option, Object value) {
        put0(option, value);
        return this;
    }

    @SuppressWarnings("unchecked")
    public final <V> V getOption(SocketOption<V> socketOption) {
        Object value = optionMap.get(socketOption);
        return value == null ? null : (V) value;
    }

    public void put0(SocketOption<Object> socketOption, Object value) {
        optionMap.put(socketOption, value);
    }
}
